home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mush-7.1.1 / signals.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-02  |  10.6 KB  |  382 lines

  1. /* @(#)signals.c    (c) copyright 10/18/86 (Dan Heller) */
  2.  
  3. #include "mush.h"
  4.  
  5. #ifndef SYSV
  6. extern char *sys_siglist[];
  7. #else
  8. /* sys-v doesn't have normal sys_siglist */
  9. static char    *sys_siglist[] = {
  10. /* no error */  "no error",
  11. /* SIGHUP */    "hangup",
  12. /* SIGINT */    "interrupt (rubout)",
  13. /* SIGQUIT */    "quit (ASCII FS)",
  14. /* SIGILL */    "illegal instruction (not reset when caught)",
  15. /* SIGTRAP */    "trace trap (not reset when caught)",
  16. /* SIGIOT */    "IOT instruction",
  17. /* SIGEMT */    "EMT instruction",
  18. /* SIGFPE */    "floating point exception",
  19. /* SIGKILL */    "kill (cannot be caught or ignored)",
  20. /* SIGBUS */    "bus error",
  21. /* SIGSEGV */    "segmentation violation",
  22. /* SIGSYS */    "bad argument to system call",
  23. /* SIGPIPE */    "write on a pipe with no one to read it",
  24. /* SIGALRM */    "alarm clock",
  25. /* SIGTERM */    "software termination signal from kill",
  26. /* SIGUSR1 */    "user defined signal 1",
  27. /* SIGUSR2 */    "user defined signal 2",
  28. /* SIGCLD */    "death of a child",
  29. /* SIGPWR */    "power-fail restart"
  30. };
  31. #endif /* SYSV */
  32.  
  33. SIGRET
  34. intrpt(sig)
  35. {
  36.     Debug("interrupt() caught: %d\n", sig);
  37.     mac_flush();
  38.     turnon(glob_flags, WAS_INTR);
  39. }
  40.  
  41. /*
  42.  * catch signals to reset state of the machine.  Always print signal caught.
  43.  * If signals are ignored, return.  If we're running the shell, longjmp back.
  44.  */
  45. /*ARGSUSED*/
  46. SIGRET
  47. catch(sig)
  48. {
  49.     Debug("Caught signal: %d\n", sig);
  50.     (void) signal(sig, catch);
  51.     if (ison(glob_flags, IGN_SIGS) && sig != SIGTERM && sig != SIGHUP)
  52.     return;
  53.     mac_flush();
  54.     print("%s: %s\n", prog_name, sys_siglist[sig]);
  55.     turnoff(glob_flags, IS_PIPE);
  56.     if (istool || sig == SIGTERM || sig == SIGHUP) {
  57.     if (istool) { /* istool is 2 if tool is complete */
  58. #if defined(SUNTOOL) && !defined(SUN_4_0)
  59.         if (sig == SIGHUP && window_get(tool, WIN_SHOW))
  60.         return;
  61. #endif /* SUNTOOL && !SUN_4_0 */
  62.         istool = 1;
  63.     }
  64.     (void) setjmp(jmpbuf);
  65.     if (ison(glob_flags, IS_GETTING))
  66.         rm_edfile(-1);
  67.     cleanup(sig);
  68.     }
  69.     if (ison(glob_flags, DO_SHELL)) {
  70.     /* wrapcolumn may have been trashed -- restore it */
  71.     if (ison(glob_flags, IS_GETTING)) {
  72.         char *fix = do_set(set_options, "wrapcolumn");
  73.         if (fix && *fix)
  74.         wrapcolumn = atoi(fix);
  75.     }
  76.     turnoff(glob_flags, IS_GETTING);
  77.     longjmp(jmpbuf, 1);
  78.     } else
  79.     puts("exiting"), cleanup(sig);
  80. }
  81.  
  82. #ifdef SIGCONT
  83. SIGRET
  84. stop_start(sig)
  85. {
  86.     extern FILE *ed_fp;
  87.  
  88.     Debug("Caught signal: %d", sig);
  89.     if (sig == SIGCONT) {
  90.     (void) signal(SIGTSTP, stop_start);
  91.     (void) signal(SIGCONT, stop_start);
  92.     echo_off();
  93.     if (istool || ison(glob_flags, IGN_SIGS) && !iscurses)
  94.         return;
  95.     /* we're not in an editor but we're editing a letter */
  96.     if (ison(glob_flags, IS_GETTING)) {
  97.         if (ed_fp)
  98.         print("(Continue editing letter)\n");
  99.     }
  100. #ifdef CURSES
  101.     else if (iscurses)
  102.         if (ison(glob_flags, IGN_SIGS)) {
  103.         clr_bot_line();
  104.         if (msg_cnt)
  105.             puts(compose_hdr(current_msg));
  106.         mail_status(1), addstr("...continue... ");
  107.         refresh();
  108.         } else {
  109.         int curlin = max(1, current_msg - n_array[0] + 1);
  110.         redraw();
  111.         print("Continue");
  112.         move(curlin, 0);
  113.         refresh();
  114.         /* make sure we lose reverse video on continuation */
  115.         if (ison(glob_flags, REV_VIDEO) && msg_cnt) {
  116.             char buf[256];
  117.             (void) strncpy(buf, compose_hdr(current_msg), COLS-1);
  118.             buf[COLS-1] = 0; /* strncpy does not null terminate */
  119.             mvaddstr(curlin, 0, buf);
  120.         }
  121.         }
  122. #endif /* CURSES */
  123.     else
  124.         mail_status(1), (void) fflush(stdout);
  125.     } else {
  126. #ifdef CURSES
  127.     if (iscurses) {
  128.         /* when user stops mush, the current header is not in reverse
  129.          * video -- note that a refresh() has not been called in curses.c!
  130.          * so, make sure that when a continue is called, the reverse video
  131.          * for the current message returns.
  132.          */
  133.         turnon(glob_flags, WAS_INTR);
  134.         if (isoff(glob_flags, IGN_SIGS) && ison(glob_flags, REV_VIDEO) &&
  135.             msg_cnt) {
  136.         int curlin = max(1, current_msg - n_array[0] + 1);
  137.         char buf[256];
  138.         scrn_line(curlin, buf);
  139.         STANDOUT(curlin, 0, buf);
  140.         }
  141.         print("Stopping...");
  142.     }
  143. #endif /* CURSES */
  144.     echo_on();
  145.     (void) signal(SIGTSTP, SIG_DFL);
  146.     (void) signal(SIGCONT, stop_start);
  147.     (void) kill(getpid(), sig);
  148.     }
  149. }
  150. #endif /* SIGCONT */
  151.  
  152. /*ARGSUSED*/
  153. void
  154. cleanup(sig)
  155. {
  156.     char buf[128], c;
  157.  
  158.     if (sig != SIGTERM && sig != SIGHUP && ison(glob_flags, IGN_SIGS))
  159.     c = 'n';
  160.     else
  161.     c = 'y';
  162.  
  163. #ifdef CURSES
  164.     if (iscurses && sig != SIGHUP)
  165.     iscurses = FALSE, endwin();
  166. #endif /* CURSES */
  167.  
  168.     echo_on();
  169.  
  170.     if (ison(glob_flags, IS_GETTING))
  171.     turnoff(glob_flags, IS_GETTING), dead_letter(sig);
  172.     if ((sig == SIGSEGV || sig == SIGBUS) && isoff(glob_flags, IGN_SIGS)
  173.         && *tempfile && !istool) {
  174.     (void) fprintf(stderr, "remove %s [y]? ", tempfile), (void) fflush(stderr);
  175.     if (fgets(buf, sizeof(buf), stdin))
  176.         c = lower(*buf);
  177.     }
  178.     if (c != 'n' && *tempfile) {
  179.     if (sig == SIGHUP && do_set(set_options, "hangup") && copyback(NULL))
  180.         (void) unlink(tempfile);
  181.     else if (unlink(tempfile) && !sig && errno != ENOENT)
  182.         error(tempfile);
  183.     }
  184.     if (sig == SIGSEGV || sig == SIGBUS) {
  185.     if (isoff(glob_flags, IGN_SIGS) && !istool) {
  186.         (void) fprintf(stderr, "coredump [n]? "), (void) fflush(stderr);
  187.         if (fgets(buf, sizeof(buf), stdin))
  188.         c = lower(*buf);
  189.     }
  190.     if (c == 'y') {
  191.         if (!istool)
  192.         puts("dumping core for debugging");
  193.         abort();
  194.     }
  195.     }
  196.     exit(sig);
  197. }
  198.  
  199. long    last_spool_size = -1;    /* declared here cuz it's initialized here */
  200.  
  201. #ifdef SUNTOOL
  202. Notify_value
  203. do_check()
  204. {
  205.     if (isoff(glob_flags, IGN_SIGS))
  206.     (void) check_new_mail();
  207.     return (NOTIFY_DONE) ;
  208. }
  209. #endif /* SUNTOOL */
  210.  
  211. /*
  212.  * Get any new mail that has arrived.  This function assumes that a
  213.  * call to mail_size() has already been done, so that last_spool_size
  214.  * can be compared to spool_size to decide what should be done.
  215.  *
  216.  * The value for last_spool_size is updated to the new spool_size only
  217.  * if update_size is TRUE.  check_new_mail() depends on the -1 initial
  218.  * value of last_spool_size for correct "New mail" messages, so it
  219.  * uses FALSE and updates last_spool_size itself.
  220.  */
  221. get_new_mail(update_size)
  222. int update_size;
  223. {
  224.     if (last_spool_size > spool_size && !strcmp(mailfile, spoolfile)) {
  225.     print("Someone changed \"%s\"!  ", mailfile);
  226.     if (update_size)
  227.         return 1;    /* Don't reinit if called from copyback() */
  228.     print_more("Reinitializing...\n");
  229.     if (isoff(glob_flags, READ_ONLY))
  230.         (void) emptyfile(&tmpf, tempfile);
  231.     current_msg = msg_cnt = 0;
  232.     }
  233.     if (load_folder(mailfile, 1, NULL) < 1) {
  234.     print("Can't load new mail: \"%s\" may be corrupted!\n", mailfile);
  235.     turnon(glob_flags, DO_UPDATE);    /* Don't reload without rewrite */
  236.     return update_size;
  237.     /* NOTE: The above is used to stop check_new_mail() from calling
  238.      * show_new_mail(), while still allowing copyback() to detect the
  239.      * possible error and to query about updating the folder.  There
  240.      * should be a better-defined way to handle this.
  241.      */
  242.     }
  243.     if (last_spool_size != spool_size) {
  244.     if (update_size)
  245.         last_spool_size = spool_size;
  246.     if (msg_cnt < last_msg_cnt)
  247.         turnoff(glob_flags, NEW_MAIL);
  248.     else {
  249.         turnon(glob_flags, NEW_MAIL);
  250.         if (current_msg < 0)
  251.         current_msg = 0;
  252.     }
  253.     return 1;
  254.     }
  255.     return 0;
  256. }
  257.  
  258. #ifdef SUNTOOL
  259. int is_iconic, was_iconic;
  260. #endif /* SUNTOOL */
  261.  
  262. /*
  263.  * Display a summary when new mail has come in.  sprintf it all into one
  264.  * buffer and print that instead of separate print statements to allow
  265.  * the tool mode to make one print statement. The reason for this is that
  266.  * when the tool is refreshed (caused by a resize, reopen, move, top, etc)
  267.  * the last thing printed is displayed -- display the entire line.
  268.  */
  269. show_new_mail()
  270. {
  271.     char        buf[BUFSIZ];
  272.     register char  *p = buf;
  273.     int           noisy = !chk_option("quiet", "newmail");
  274. #ifdef CURSES
  275.     int new_hdrs = last_msg_cnt;
  276. #endif /* CURSES */
  277.  
  278.     if (msg_cnt == last_msg_cnt)
  279.     return 1;    /* Nothing to print */
  280. #ifdef SUNTOOL
  281.     if (istool) {
  282.     mail_status(0);
  283.     (void) do_hdrs(0, DUBL_NULL, NULL);
  284.     if (noisy && !chk_option("quiet", "tool"))
  285.         bell();
  286.     }
  287. #endif /* SUNTOOL */
  288.     if (msg_cnt < last_msg_cnt) {
  289.     last_msg_cnt = msg_cnt;
  290.     if (!istool)
  291.         mail_status(0);
  292.     if (iscurses && isoff(glob_flags, CNTD_CMD))
  293.         (void) do_hdrs(0, DUBL_NULL, NULL);
  294.     return 0;
  295.     }
  296.     if (noisy) {
  297.     p += Strcpy(p, "New mail ");
  298.     if (msg_cnt - last_msg_cnt <= 1)
  299.         p += strlen(sprintf(p, "(#%d) ", msg_cnt));
  300.     else
  301.         p += strlen(sprintf(p, "(#%d thru #%d)\n", last_msg_cnt+1,msg_cnt));
  302.     }
  303. #ifdef SUNTOOL
  304.     /*
  305.      * If mush is in tool mode and in icon form, don't update
  306.      * last_msg_cnt so that when the tool is opened, print() will
  307.      * print the correct number of "new" messages.
  308.      */
  309.     if (istool && (was_iconic = (int) window_get(tool, FRAME_CLOSED)))
  310.     (void) strcpy(p, "\n");
  311.     else
  312. #endif /* SUNTOOL */
  313.     {
  314.     if (!noisy || iscurses && isoff(glob_flags, CNTD_CMD))
  315.         last_msg_cnt = msg_cnt;
  316.     else while (last_msg_cnt < msg_cnt) {
  317.         char *p2 = compose_hdr(last_msg_cnt++) + 9;
  318.         if (strlen(p2) + (p - buf) >= BUFSIZ-5) {
  319.         (void) strcpy(p, "...\n");
  320.         /* force a break by setting last_msg_cnt correctly */
  321.         last_msg_cnt = msg_cnt;
  322.         } else
  323.         p += strlen(sprintf(p, " %s\n", p2));
  324.     }
  325.     }
  326. #ifdef CURSES
  327.     if (iscurses && isoff(glob_flags, CNTD_CMD)) {
  328.     if (new_hdrs - n_array[screen-1] < screen)
  329.         (void) do_hdrs(0, DUBL_NULL, NULL);
  330.     print("%s ...", buf);
  331.     } else
  332. #endif /* CURSES */
  333.     if (noisy)
  334.         print("%s", buf); /* buf might have %'s in them!!! */
  335.     return 1;
  336. }
  337.  
  338. /*
  339.  * Look for new mail and read it in if any has arrived.
  340.  * return 0 if no new mail, 1 if new mail and -1 if new mail is in system
  341.  * folder, but current mbox is not system mbox.
  342.  */
  343. check_new_mail()
  344. {
  345.     int        ret_value;
  346.  
  347.     /* if fullscreen access in progress (help), don't do anything */
  348.     if (ret_value = mail_size()) {
  349. #ifdef SUNTOOL
  350.     /* if our status has changed from icon to open window, then
  351.      * there will already be a message stating number of new
  352.      * messages.  reset `n' to msg_cnt so we don't restate
  353.      * the same # of new messages upon receipt of yet another new message.
  354.      */
  355.     if (istool && !(is_iconic = ((int) window_get(tool, FRAME_CLOSED))) &&
  356.         was_iconic)
  357.         last_msg_cnt = msg_cnt;
  358. #endif /* SUNTOOL */
  359.     if (get_new_mail(0) && !show_new_mail())
  360.         return 0;
  361.     } else
  362. #ifdef SUNTOOL
  363.     if (!istool || !is_iconic)
  364. #endif /* SUNTOOL */
  365.         turnoff(glob_flags, NEW_MAIL);
  366.     if (last_spool_size > -1 && /* handle first case */
  367.         strcmp(mailfile, spoolfile) && last_spool_size < spool_size)
  368.     print("You have new mail in your system mailbox.\n"), ret_value = -1;
  369.     last_spool_size = spool_size;
  370.     return ret_value;
  371. }
  372.  
  373. /*ARGSUSED*/   /* we ignore the sigstack, cpu-usage, etc... */
  374. SIGRET
  375. bus_n_seg(sig)
  376. {
  377.     (void) signal(sig, SIG_DFL);
  378.     (void) fprintf(stderr, "%s: %s\n", prog_name,
  379.     (sig == SIGSEGV)? "Segmentation violation": "Bus error");
  380.     cleanup(sig);
  381. }
  382.